package com.owen.springboot.smartparkingms.module.app.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.owen.springboot.smartparkingms.common.constant.SystemConstant;
import com.owen.springboot.smartparkingms.common.model.Result;
import com.owen.springboot.smartparkingms.common.util.CommonUtils;
import com.owen.springboot.smartparkingms.common.util.DateUtils;
import com.owen.springboot.smartparkingms.module.app.entity.*;
import com.owen.springboot.smartparkingms.module.app.service.*;
import com.owen.springboot.smartparkingms.module.app.util.BaiDuUtils;
import com.owen.springboot.smartparkingms.module.app.util.CostUtils;
import com.owen.springboot.smartparkingms.module.app.util.NearSpaceUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/app/distinguish")
public class DistinguishController {

    @Value("${file.path}")
    private String filePath;

    @Autowired
    private BaiDuUtils baiDuUtils;

    @Autowired
    private IParkService parkService;

    @Resource
    private ICarService carService;

    @Autowired
    private ICarParkRecordService carParkingRecordService;

    @Resource
    private ICarOrderService carOrderService;

    @Resource
    private IParkAreaService parkAreaService;

    @Resource
    private IParkStatusService parkStatusService;

    /**
     * 演示上传
     */
    @RequestMapping("upload")
    public Result upload(MultipartFile file, Long id) {
        try {
            if(file!=null){
                /**
                 * 当图片文件不为空时，根据id查询出对应的停车场
                 */
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("park_id", id);
                Park park = parkService.getOne(queryWrapper);
                if(id==null||park==null){
                    return Result.error("请选择停车场");
                }
                /**
                 * 对上传图片进行重命名并保存到对应日期的目录下
                 */
                File parentFile = CommonUtils.createParentFile(filePath);  //在上传路径下根据按年月日创建多级目录
                String fileName = file.getOriginalFilename();
                String suffix = fileName.substring(fileName.lastIndexOf("."));  //获取图片后缀
                String uuid = IdUtil.simpleUUID();
                fileName = uuid + suffix;  //生成UUID后给上传图片重命名
                File imageFile = new File(parentFile,fileName);
                FileUtil.writeFromStream(file.getInputStream(), imageFile);  //把上传图片写入到重命名后的文件
                String fileDay = DateUtil.thisYear()+"/"+(DateUtil.thisMonth()+1)+"/"+DateUtil.thisDayOfMonth();
                String imagePath = SystemConstant.FILE + "/" + fileDay+"/"+fileName; //上传图片的完整路径
                /**
                 * 进行车牌识别
                 */
                String plateNumber = baiDuUtils.plateLicense(imageFile.getAbsolutePath()); //获取车牌号码plateNumber
                if(StringUtils.isBlank(plateNumber)){
                    return Result.error("识别失败");
                }
                Map<String, Object> map = new HashMap<>(); //用map把所有需要返回的信息装起来
                map.put("plateNumber",plateNumber);
                map.put("imagePath",imagePath);
                map.put("parkId",id);
                /**
                 * 判断是否为新入场车
                 */
                QueryWrapper queryIsNew = new QueryWrapper();
                queryIsNew.eq("plate_number",plateNumber); //按车牌号查询有无登记过的车辆
                Car car = carService.getOne(queryIsNew);
                int type;
                if(car==null){  // 没有登记过则新增车辆信息，并登记为临时车
                    Car newCar = new Car();
                    newCar.setPlateNumber(plateNumber);
                    newCar.setGmtCreate(DateUtils.getTimestamp());
                    newCar.setStatus(2);
                    newCar.setParkId(id);
                    carService.save(newCar);
                    type = 2;
                    map.put("type","临时车");
                }else {  // 有登记过则修改最近入场时间以及停车场id
                    car.setGmtModified(DateUtils.getTimestamp());
                    car.setParkId(id);
                    carService.saveOrUpdate(car);
                    type = car.getStatus();
                    if(type==0){
                        map.put("type","包月车");
                    }else if(type==1) {
                        map.put("type","VIP车");
                    }else {
                        map.put("type","临时车");
                    }
                }
                /**
                 * 查询进出场记录并进行对应进出场操作
                 */
                QueryWrapper queryRecord = new QueryWrapper();
                queryRecord.eq("plate_number", plateNumber);
                queryRecord.eq("park_id",id);
                queryRecord.isNull("gmt_out");
                CarParkRecord record = carParkingRecordService.getOne(queryRecord);
                //  出场操作：计算费用，生成订单，记录出场时间，修改车位信息
                if(record!=null){
                    record.setCost(CostUtils.calculate(record,park));
                    record.setGmtOut(DateUtils.getTimestamp());
                    map.put("msg","出场成功");
                    UpdateWrapper updateParkStatus = new UpdateWrapper();
                    updateParkStatus.eq("plate_number",plateNumber);
                    updateParkStatus.set("plate_number", null);
                    updateParkStatus.set("status","空位");
                    parkStatusService.update(updateParkStatus);
                    /**
                     * 如果是临时车生成支付订单
                     */
                    if(type == SystemConstant.CAR_TYPE_TEMP){
                        CarOrder carOrder = new CarOrder();
                        carOrder.setBody("停车费订单");
                        carOrder.setParkId(id);
                        carOrder.setGmtCreate(DateUtils.getTimestamp());
                        String orderNo = DateUtils.format(new Timestamp(System.currentTimeMillis()),"yyyymmddhhmmss");
                        carOrder.setOrderNo(orderNo);
                        carOrder.setPlateNumber(plateNumber);
                        carOrder.setType(1);
                        carOrder.setStatus(1);
                        carOrder.setTotalFee(CostUtils.calculate(record,park));
                        carOrder.setTime(CostUtils.takeTime(record,park));
                        carOrderService.save(carOrder);
                        record.setOrderNo(orderNo);
                    }
                }else{ //入场操作
                    record = new CarParkRecord();
                    record.setParkId(id);
                    record.setGmtInto(DateUtils.getTimestamp());
                    record.setPlateNumber(plateNumber);
                    record.setType(type);
                    map.put("msg","进场成功");

                    QueryWrapper queryParkId = new QueryWrapper();
                    queryParkId.eq("park_id" , id);
//                    queryWrapper3.last(" and space_far_entrance = " +
//                            "(select MIN(space_far_entrance) from app_park_area)");
                    List<ParkArea> areaList = parkAreaService.list(queryParkId);
                    List<ParkStatus> statusList = parkStatusService.list(queryParkId);
                    String nearSpace = NearSpaceUtils.getNearSpace(areaList,statusList); // 获取最近车位名
                    map.put("nearSpace" , nearSpace);
                }
                carParkingRecordService.saveOrUpdate(record);
                return Result.ok(map);
            }else{
                return Result.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
    }

}
